  //
  //  LogManager.swift
  //  hello
  //
  //  Created by 赵康 on 2025/2/13.
  //
import SwiftyBeaver
import Foundation


  // MARK: - 日志记录协议
protocol Logging {
  var log: SwiftyBeaver.Type { get }
}

extension Logging {
  var log: SwiftyBeaver.Type { SwiftyBeaver.self }
}

  // MARK: - 日志管理器
final class LogManager: @unchecked Sendable, Logging {
  static let shared = LogManager()
  private var destinations: [BaseDestination] = []
  private init() { }
  
  private func addDestination(_ destination: BaseDestination) {
    destinations.append(destination)
    SwiftyBeaver.addDestination(destination)
  }
  
  private func removeDestination(_ destination: BaseDestination) {
    if let index = destinations.firstIndex(where: { $0 === destination }) {
      destinations.remove(at: index)
      SwiftyBeaver.removeDestination(destination)
    }
  }
    // MARK: - 日志格式配置
  enum Format: String {
      /// 简洁格式
    case brief
      /// 标准格式
    case standard
      /// 详细格式
    case verbose
    
    var pattern: String {
      switch self {
        case .brief:
          return "[$C$L$c] $M" // 仅显示消息
          
        case .standard: // 显示月份|时间|函数名|文件名|行号|消息
          return """
                $C$L$c [$D MM-dd HH:mm:ss.SSS$d] $N|$F|$l | $M
                """
          
        case .verbose:
          return """
            $C$L$c
            消息: $M
            数据: $X
            行号: $l
            文件名: $N
            函数名: $F
            [$D MM-dd HH:mm:ss.SSS$d]
            """
      }
    }
  }
  
    // MARK: - 日志级别配置
  private func configureLevelString(_ destination: ConsoleDestination) {
    destination.levelString.verbose = "详细数据"
    destination.levelString.debug = "调试"
    destination.levelString.info = "通知"
    destination.levelString.warning = "警告"
    destination.levelString.error = "错误"
    destination.levelString.critical = "致命"
  }
  
  private func configureLevelColor(_ destination: ConsoleDestination) {
    destination.useTerminalColors = true
  }

    // MARK: - 配置方法
  func configure() {
    configureConsole()
    configureFilters()
  }
  
  private func configureConsole() {
    let console = ConsoleDestination()
    
      // 基础配置
    console.format = Format.verbose.pattern  // 默认使用详细格式
    console.asynchronously = false
    console.minLevel = .verbose
    console.calendar = Calendar.current
    
      // 配置日志级别样式
    configureLevelString(console)
    configureLevelColor(console)
    
    addDestination(console)
  }
}

extension LogManager {
  func log(_ level: SwiftyBeaver.Level, _ message: @autoclosure () -> Any, format: Format = .standard, file: String = #file, function: String = #function, line: Int = #line, context: Any? = nil) {
      // 1. 暂存当前的 destinations
    let currentDestinations = destinations
    
      // 2. 移除所有现有的 destinations
    currentDestinations.forEach { removeDestination($0) }
    
      // 3. 创建新的临时 destination
    let tempDestination = ConsoleDestination()
    tempDestination.format = format.pattern
    tempDestination.asynchronously = false
    configureLevelString(tempDestination)
    configureLevelColor(tempDestination)
    
      // 4. 添加临时 destination
    addDestination(tempDestination)
    
      // 5. 记录日志
    log.custom(level: level, message: message(), file: file, function: function, line: line, context: context)
    
      // 6. 移除临时 destination
    removeDestination(tempDestination)
    
      // 7. 恢复原有的 destinations
    currentDestinations.forEach { addDestination($0) }
  }
  
    // 便捷方法
  func verbose(_ message: @autoclosure () -> Any, format: Format = .standard, file: String = #file, function: String = #function, line: Int = #line, context: Any? = nil) {
    log(.verbose, message(), format: format, file: file, function: function, line: line, context: context)
  }
  
  func debug(_ message: @autoclosure () -> Any, format: Format = .standard, file: String = #file, function: String = #function, line: Int = #line, context: Any? = nil) {
    log(.debug, message(), format: format, file: file, function: function, line: line, context: context)
  }
  
  func info(_ message: @autoclosure () -> Any, format: Format = .standard, file: String = #file, function: String = #function, line: Int = #line, context: Any? = nil) {
    log(.info, message(), format: format, file: file, function: function, line: line, context: context)
  }
  
  func warning(_ message: @autoclosure () -> Any, format: Format = .standard, file: String = #file, function: String = #function, line: Int = #line, context: Any? = nil) {
    log(.warning, message(), format: format, file: file, function: function, line: line, context: context)
  }
  
  func error(_ message: @autoclosure () -> Any, format: Format = .standard, file: String = #file, function: String = #function, line: Int = #line, context: Any? = nil) {
    log(.error, message(), format: format, file: file, function: function, line: line, context: context)
  }
}

// MARK: - 配置过滤规则
extension LogManager {
    /// # 可用的过滤目标
    /// `Filters.Path`      // 基于文件路径过滤
    /// `Filters.Function`  // 基于函数名过滤
    /// `Filters.Message`   // 基于日志消息内容过滤
  
    /// # 下边定义的这些规则相当于筛选条件,其中:
    /// `required=true`表示必须满足这个条件才会**记录日志**,对个required是与的关系
    /// `required=false`满足其中一个条件就会记录日志,多个non-required是或的关系
    /// `excludes`过滤器将匹配的内容排除
    ///
    ///  # 以下方法对所有过滤目标都适用
    /// `.startsWith`("prefix...")    // 以特定字符串开头
    /// `.contains`("text...")       // 包含特定字符串
    /// `.excludes`("text...")      // 不包含特定字符串
    /// `.endsWith`("suffix...")    // 以特定字符串结尾
    /// `.equals`("exact...")       // 完全匹配
    /// `.custom` { text in ... }   // 自定义过滤规则
  
  func configureFilters() {
    
    let filters = [
      createFrameworkFilter(),
      createMethodFilter(),
      createMessageFilter(),
      createCustomFilter(),
      createUserControllerFilter(),
      createLevelFilter()
    ]
    
      // 应用过滤器到所有目标
    destinations.forEach { destination in
      filters.forEach { filter in
        destination.addFilter(filter)
      }
    }
    
      // 1. 路径过滤
    func createFrameworkFilter() -> FilterType {
      return Filters.Path.contains(
        "Vapor", "NIO",
        caseSensitive: false,
        required: false,
        minLevel: .info
      )
    }
    
      // 2. 函数名过滤
    func createMethodFilter() -> FilterType {
      let methodFilter = Filters.Function.contains(
        "registerControllers",
        caseSensitive: true,
        required: false,
        minLevel: .debug
      )
      return methodFilter
    }
    
      // 3. 消息内容过滤
    func createMessageFilter() -> FilterType {
      let messageFilter = Filters.Message.excludes(
        "heartbeat", "ping",
        caseSensitive: false,
        required: false,
        minLevel: .debug
      )
      return messageFilter
    }
    
      // 4. 自定义过滤规则
    func createCustomFilter() -> FilterType {
      let customFilter = Filters.Message.custom(
        required: false,
        minLevel: .debug
      ) { message in
          // 过滤掉敏感信息的日志
        !message.contains("password") &&
        !message.contains("token")
      }
      return customFilter
    }
    
      // 5. 特定文件的详细日志
    func createUserControllerFilter() -> FilterType {
      let userControllerFilter = Filters.Path.equals(
        "UserController",
        caseSensitive: false,
        required: false,    // 必须满足则为true
        minLevel: .verbose // 允许详细日志
      )
      return userControllerFilter
    }
    
      // 6. 只记录特定级别的日志
    func createLevelFilter() -> FilterType {
      let levelFilter = Filters.Message.custom(
        required: false,
        minLevel: .verbose
      ) { _ in true }
      return levelFilter
    }
    
  }
}
